<template>
  <div>
    <div class="content">
      <div>内容一</div>
      <div>内容二</div>
      <div>内容三</div>
      <div>内容四</div>
      <div>内容五</div>
    </div>
    <ul class="navs">
      <li :class="{ active: active === 0 }" @click="scrollTo(0)">导航一</li>
      <li :class="{ active: active === 1 }" @click="scrollTo(1)">导航二</li>
      <li :class="{ active: active === 2 }" @click="scrollTo(2)">导航三</li>
      <li :class="{ active: active === 3 }" @click="scrollTo(3)">导航四</li>
      <li :class="{ active: active === 4 }" @click="scrollTo(4)">导航五</li>
    </ul>
  </div>

</template>

<!--留着先-->
<script>
export default {
  name: `Test`,
  data() {
    return {
      active: 0
    }
  },
  mounted() {
    window.addEventListener('scroll', this.onscroll)
  },
  methods: {
    onscroll() {
      const navContents = document.querySelectorAll('.content div')
      // 存储所有div元素的 offsetTop
      const offsetTopArr = []

      navContents.forEach((item) => {
        offsetTopArr.push(item.offsetTop)
      })
      const scrollTop =
          document.body.scrollTop || document.documentElement.scrollTop
      // 定义当前高亮的导航下标
      let navIndex = 0

      for (let n = 0; n < offsetTopArr.length; n++) {
        if (scrollTop >= offsetTopArr[n]) {
          navIndex = n
        }
      }
      this.active = navIndex
    },
    // 跳转到指定索引的元素
    scrollTo(index) {
      // 获取目标的 offsetTop
      const targetOffsetTop = document.querySelector(`.content div:nth-child(${index + 1})`).offsetTop
      // 获取当前 offsetTop
      let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
      // 定义一次跳 50 个像素
      const STEP = 100
      // 判断是往下滑还是往上滑
      if (scrollTop > targetOffsetTop) {
        // 往上滑
        smoothUp()
      } else {
        // 往下滑
        smoothDown()
      }

      function smoothDown() {
        // 如果当前 scrollTop 小于 targetOffsetTop 说明视口还没滑到指定位置
        if (scrollTop < targetOffsetTop) {
          // 如果和目标相差距离大于等于 STEP 就跳 STEP
          // 否则直接跳到目标点，目标是为了防止跳过了。
          if (targetOffsetTop - scrollTop >= STEP) {
            scrollTop += STEP
          } else {
            scrollTop = targetOffsetTop
          }
          document.body.scrollTop = scrollTop
          document.documentElement.scrollTop = scrollTop
          // 屏幕在绘制下一帧时会回调传给 requestAnimationFrame 的函数
          requestAnimationFrame(smoothDown)
        }
      }
      function smoothUp() {
        if (scrollTop > targetOffsetTop) {
          if (scrollTop - targetOffsetTop >= STEP) {
            scrollTop -= STEP
          } else {
            scrollTop = targetOffsetTop
          }
          document.body.scrollTop = scrollTo
          document.documentElement.scrollTop = scrollTo
          requestAnimationFrame(smoothUp)
        }
      }
    }
  }
}
</script>

<style scoped>
  .content {
    background-color: white;
    width: 500px;
  }
  .content div {
    width: 100%;
    height: 600px;
    font-size: 36px;
    padding: 20px;
    background-color: #7ec384;
  }
  .content div:nth-child(2n) {
    background-color: #847ec3;
  }
  .navs {
    position: fixed;
    top: 80px;
    width: 100px;
    left: 700px;
    background-color: skyblue;
  }
  .navs li {
    padding: 0 20px;
    width: 100%;
    list-style: none;
    font-size: 24px;
  }
  .navs .active {
    color: #847ec3;
    background-color: red;
  }
</style>
